#include "NEventQueue.h"
#include "NeroCore\NMemoryManager.h"

using namespace Engine;

NEventQueue* NEventQueue::sInstance = NULL;

NEventQueue::NEventQueue()
{
}

NEventQueue::~NEventQueue()
{
	Clear(1000,true);
}

void NEventQueue::Initialize()
{
	if (sInstance == NULL)
	{
		sInstance = MY_NEW(Memory::HID_Engine,"EventQue") NEventQueue();
	}
}

void NEventQueue::Deinitialize()
{
	if (sInstance != NULL)
	{
		MY_DELETE( sInstance ); 
		sInstance = NULL;
	}
	else{throw std::exception("Nothing to destroy");}
}

NEventQueue* NEventQueue::GetInstance()
{
	return sInstance;
}

void NEventQueue::Enqueue(NEventPublisher * aEP, float currentWallTime, float delayTime /* = 0.0 */)
{
	aEP->SetTime(currentWallTime,delayTime);
	mQueue.push_front(aEP);
}

void NEventQueue::Send(const NEventPublisher * aEP,const double &)
{
	aEP->Deliver();
}

void NEventQueue::Update(float currentTime)
{
	Queue::iterator _it = mQueue.begin();
	
	//activate all events that have expired
	for(;_it != mQueue.end();_it++)
	{
		NEventPublisher * event = *_it;
		if(event->IsExpired(currentTime))
		{
			event->Deliver();
			mRemoveQueue.push_front(event);
		}
	}

	_it = mRemoveQueue.begin();
	//delete all events that need to be removed
	for(;_it != mRemoveQueue.end();_it++)
	{
		NEventPublisher* event = *_it;
		if(event != NULL && event->IsDeletedAfterPublishing())
		{
			mQueue.remove(event);
			MY_DELETE( event );
		}
	}	
	mRemoveQueue.clear();
}

void NEventQueue::Clear(float currentTime, bool deliverExpierd)
{
	if(deliverExpierd)
	{ 
		Update(currentTime);
	}
	mQueue.clear();
}

unsigned int NEventQueue::Size() const
{
	return mQueue.size();
}

